﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using IdentityModel;
using StackExchange.Redis;

namespace AgencyManagerSystem.Common
{
    public static class TokenManager
    {
        public static TokenValidationParameters GetValidationParameters()
        {
            var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Variable.SECRETKEY));
            var tokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,
                ValidateIssuerSigningKey = false,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidIssuer = Variable.VALIDISSUER,
                ValidAudience = Variable.VALIDAUDIENCE,
            };
            LogHelper.Log(typeof(TokenManager).Name,"正在获取Token验证参数");
            return tokenValidationParameters;
        }
        public static string GenerateToken(UserProfile userProfile,out int expires,out DateTime authTime)
        {
            if(userProfile==null)
            {
                LogHelper.Err(typeof(TokenManager).Name, "GenerateToken:传入了错误的参数Profile");
                expires = 0;
                authTime = DateTime.Now;
                return "";
            }
            LogHelper.Log(typeof(TokenManager).Name,String.Format( "用户{0}正在请求生成Token",userProfile.UserId));
            expires = Variable.EXPIRES;
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Variable.SECRETKEY));
            authTime = DateTime.Now;
            var expiresAt = authTime.AddSeconds(Variable.EXPIRES);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(JwtClaimTypes.Audience,Variable.VALIDAUDIENCE),
                    new Claim(JwtClaimTypes.Issuer,Variable.VALIDISSUER),
                    new Claim(JwtClaimTypes.Id, userProfile.UserId.ToString()),
                    new Claim(MyJwtClaimTypes.Domain,userProfile.Domain.ToString())
                }),
                Expires = expiresAt,
                SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature)
            };
            string result = "";
            try
            {
                var token = tokenHandler.CreateToken(tokenDescriptor);
                result = tokenHandler.WriteToken(token);
                TimeSpan timeSpan = new TimeSpan(0, 0, Variable.EXPIRES);
                //RedisCacheHelper.StringSet(result, result, timeSpan);//本策略不考虑单用户登录要求
            }
            catch(Exception ex)
            {
                LogHelper.Err(typeof(TokenManager).Name,String.Format( "GenerateToken:系统异常{0}-{1}", ex.Message, ex.StackTrace));
            }
            return result;
        }
        public static void DisableToken(string token)
        {
            LogHelper.Log(typeof(TokenManager).Name, "DisableToken:正在失效Token");
           // bool result = RedisCacheHelper.StringDelete(token);
            LogHelper.Log(typeof(TokenManager).Name, "DisableToken:Token"+token+"被标记为失败");

        }

        public static UserProfile RestoreToken(string token)
        {
            LogHelper.Log(typeof(TokenManager).Name, "RestoreToken:正在还原Token");
            if (String.IsNullOrWhiteSpace(token))
            {
                LogHelper.Err(typeof(TokenManager).Name, "RestoreToken:还原Token失败");
                return null;
            }
          //  RedisValue cache = (RedisValue)RedisCacheHelper.StringGet(token)  ;
            /*if (cache.IsNull)
            {
                LogHelper.Err(typeof(TokenManager).Name, "RestoreToken:Token已经被标记为失效");
                return null;
            }*/
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Variable.SECRETKEY));
            SecurityToken securityToken;
            try
            {
                var principal = tokenHandler.ValidateToken(token, GetValidationParameters(), out securityToken);
                JwtSecurityToken jwtSecurityToken = securityToken as JwtSecurityToken;
                UserProfile userProfile = new UserProfile();
                userProfile.UserId = Int32.Parse(jwtSecurityToken.Payload[JwtClaimTypes.Id].ToString());
                userProfile.Domain = Int32.Parse(jwtSecurityToken.Payload[MyJwtClaimTypes.Domain].ToString());
                return userProfile;
            }
            catch(Exception ex)
            {
                LogHelper.Err(typeof(TokenManager).Name,ex.Message+"-"+ex.StackTrace);
                return null;
            }
        }
    }
}
